#ifndef				GAME_STATE_H
#define				GAME_STATE_H

//////////////////////////////////////////////////////////////////////////
#include <list>
#include "AppState.h"
#include "Dotsceneloader.h"

#include <OgreSubEntity.h>
#include <Terrain/OgreTerrain.h>
#include <Terrain/OgreTerrainGroup.h>
#include <list>
#include <fmod.h>
#include <fmod_errors.h>

#include "TerrainEx.h"
#include "Spirit.h"
#include "CameraEx.h"
#include "Mushroom.h"
#include "Ninja.h"

#define TERRAINWORLDSIZE 1000
#define BLENDMAPWORLDSIZE 10


//////////////////////////////////////////////////////////////////////////
enum	QueryFlags
{
	OGRE_HEAD_MASK		= 1 << 0,
	CUBE_MASK			= 1 << 1
};

//////////////////////////////////////////////////////////////////////////

class GameState : public AppState
{
public:
	GameState();
	DECLARE_APPSTATE_CLASS(GameState);

	void	enter();
	void	createScene();
	void	exit();
	bool	pause();
	void	resume();

	void	moveCamera();
	void	getInput();
	void	buildGUI();

	bool	keyPressed(const OIS::KeyEvent &arg);
	bool	keyReleased(const OIS::KeyEvent &arg);

	bool	mouseMoved(const OIS::MouseEvent &arg);
	bool	mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id);
	bool	mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id);

	void	onLeftPressed(const OIS::MouseEvent &evt);
	void	itemSelected(OgreBites::SelectMenu* menu);

	void	moveEntity(const OIS::KeyEvent	&arg);
	void	moveEntityRay(const Ogre::FrameEvent&	evt);
	
	void	update(double	timeSinceLastFrame);
	void	setupSun();

	void	addCollisiontoScirit();	

	//////////////////////////////////////////////////////////////////////////

	void	createNinja();
	void	updateNinja(const Ogre::FrameEvent&	evt);
	void	calculateDead();
	
	void	createMushroom(Vector3 pos);
	void	updateMushroom(const Ogre::FrameEvent&	evt);

	//////////////////////////////////////////////////////////////////////////
	void	createSound();
	void	exitSound();

	//////////////////////////////////////////////////////////////////////////
	// The environment object
	void	createEnviromentObject();

protected:
private:
	Ogre::SceneNode*			m_pOgreHeadNode;
	Ogre::Entity*				m_pOgreHeadEntity;

	Ogre::MaterialPtr			m_pOgreHeadMat;
	Ogre::MaterialPtr			m_pOgreHeadMatHigh;
	
	OgreBites::ParamsPanel*		m_pDetailsPanel;
	bool						m_bQuit;
	Real						m_rtc;
	Ogre::AnimationState*		m_pAnimationState;
	

	//////////////////////////////////////////////////////////////////////////
	// custom object
	TerrainEx*					m_pterrain;
	Spirit*						m_pSinbad;
	CameraEx*					m_pCamerEx;
	Mushroom*					m_pMushroom;
	Ninja*						m_pNinja;

	std::list<Ninja*>			m_lNinjaGroup;
	std::vector<Mushroom*>		m_vMushRoom;
	int							m_nNinjaNum;	
	
	Real						m_rTime;
	bool						m_bAddConlission;
	//////////////////////////////////////////////////////////////////////////
	Ogre::Entity*				m_pcolumnEntity;
	Ogre::SceneNode*			m_pcolumNode;

	std::vector<SceneNode*>		m_vEnviromentObjectNode;
	//////////////////////////////////////////////////////////////////////////
	// sound
	FMOD_SYSTEM		*fsystem;
	FMOD_SOUND		*cdsound;
	FMOD_CHANNEL	*channel;
	FMOD_RESULT		result;
	unsigned int    version;
};

#endif